package com.book.service.impl;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.CannedAccessControlList;
import com.book.service.LoadImageService;
import com.book.utils.ResponseResult;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

/**
 * 此服务类目的是上传图片至服务器，但是我偷懒了没有将公共部分独立一个方法出来，因此这里很冗余
 */
//错误码从5001开始
@Service
public class LoadImageServiceImpl implements LoadImageService {

    /**
     * 下面四个变量具体解释看yml配置文件即可
     */

    //节点
    @Value("${oss.endpoint}")
    private String endpoint;

    //桶名
    @Value("${oss.bucketName}")
    private String bucketName;

    //oss id
    @Value("${oss.accessKeyId}")
    private String accessKeyId;

    //oss密钥
    @Value("${oss.accessKeySecret}")
    private String accessKeySecret;

    @Override
    public ResponseResult loadHead(String userId, MultipartFile multipartFile) {
        if(multipartFile.isEmpty()) return new ResponseResult(5001,"上传图片为空");
        // 创建OSSClient实例。，暂时不用环境变量的方式
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        //判断oss桶是否存在，不存在则创建一个
        if(!ossClient.doesBucketExist(bucketName)) {
            //创建一个bucker
            ossClient.createBucket(bucketName);
            //设置oss实例访问权限；公共读
            ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
        }
        try {
            //1、获取文件上传的流
            //虽然配置文件写了限制文件大小，但是我们需要自定义返回错误信息
            if(multipartFile.getSize()/1024/1024>2){
                return new ResponseResult(5002,"头像太大啦，换小点的吧。");
            }
            InputStream inputStream = multipartFile.getInputStream();
            //2、构建用户头像目录  head/userId/2024-03-03/图片
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String datePath = "head/" + userId + "/" + dateFormat.format(new Date());//构建头像存放的目录
            //3、获取文件名
            String originName = multipartFile.getOriginalFilename();//这是文件在本地的名字，包括后缀
            String filename = UUID.randomUUID().toString();//用uuid生成一个新的名字
            assert originName != null;
            String suffix = originName.substring(originName.lastIndexOf("."));//把文件后缀获取出来
            //这里判断一下后缀是否是jpg,png
            if(!".jpg".equals(suffix) && !".png".equals(suffix) && !".jpeg".equals(suffix))
                return new ResponseResult(5003,"文件格式不正确，请重新选择!");
            String newName = filename+suffix;//保存在服务器上的头像名字就是uuid加上截取的后缀
            String fileUrl = datePath+"/"+newName;//头像目录加本身的头像文件
            //4、文件上传到阿里云服务器
            ossClient.putObject(bucketName, fileUrl, inputStream);
            String complete = "https://"+bucketName+"."+endpoint+"/"+fileUrl;//构建完整的头像地址
            return new ResponseResult(200,"头像上传成功",complete);
        } catch (OSSException | ClientException | IOException oe) {
            oe.printStackTrace();
            return new ResponseResult(5004,"头像上传失败");
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    @Override
    public ResponseResult loadPostHead(String userId, MultipartFile multipartFile) {
        if(multipartFile.isEmpty()) return new ResponseResult(5005,"上传图片为空");
        // 创建OSSClient实例。，暂时不用环境变量的方式
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        //判断oss桶是否存在，不存在则创建一个
        if(!ossClient.doesBucketExist(bucketName)) {
            //创建一个bucker
            ossClient.createBucket(bucketName);
            //设置oss实例访问权限；公共读
            ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
        }
        try {
            //1、获取文件上传的流
            //虽然配置文件写了限制文件大小，但是我们需要自定义返回错误信息
            if(multipartFile.getSize()/1024/1024>9){
                return new ResponseResult(5006,"图片太大啦");
            }
            InputStream inputStream = multipartFile.getInputStream();
            //2、构建用户头像目录  head/userId/2024-03-03/图片
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String datePath = "post/" + userId + "/" + dateFormat.format(new Date());//构建头像存放的目录
            //3、获取文件名
            String originName = multipartFile.getOriginalFilename();//这是文件在本地的名字，包括后缀
            String filename = UUID.randomUUID().toString();//用uuid生成一个新的名字
            assert originName != null;
            String suffix = originName.substring(originName.lastIndexOf("."));//把文件后缀获取出来
            //这里判断一下后缀是否是jpg,png
            if(!".jpg".equals(suffix) && !".png".equals(suffix) && !".jpeg".equals(suffix))
                return new ResponseResult(5006,"文件格式不正确，请重新选择!");
            String newName = filename+suffix;//保存在服务器上的头像名字就是uuid加上截取的后缀
            String fileUrl = datePath+"/"+newName;//头像目录加本身的头像文件
            //4、文件上传到阿里云服务器
            ossClient.putObject(bucketName, fileUrl, inputStream);
            String complete = "https://"+bucketName+"."+endpoint+"/"+fileUrl;//构建完整的头像地址
            return new ResponseResult(200,"图片上传成功",complete);
        } catch (OSSException | ClientException | IOException oe) {
            oe.printStackTrace();
            return new ResponseResult(5007,"图片上传失败");
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    @Override
    public ResponseResult loadBookImage(String bookId, MultipartFile multipartFile) {
        if(multipartFile.isEmpty()) return new ResponseResult(5008,"上传图片为空");
        // 创建OSSClient实例。，暂时不用环境变量的方式
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        //判断oss桶是否存在，不存在则创建一个
        if(!ossClient.doesBucketExist(bucketName)) {
            //创建一个bucker
            ossClient.createBucket(bucketName);
            //设置oss实例访问权限；公共读
            ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
        }
        try {
            //1、获取文件上传的流
            //虽然配置文件写了限制文件大小，但是我们需要自定义返回错误信息
            if(multipartFile.getSize()/1024/1024>9){
                return new ResponseResult(5009,"图片太大啦");
            }
            InputStream inputStream = multipartFile.getInputStream();
            //2、构建用户头像目录  head/userId/2024-03-03/图片
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String datePath = "book/" + bookId + "/" + dateFormat.format(new Date());//构建书籍图片存放的目录
            //3、获取文件名
            String originName = multipartFile.getOriginalFilename();//这是文件在本地的名字，包括后缀
            String filename = UUID.randomUUID().toString();//用uuid生成一个新的名字
            assert originName != null;
            String suffix = originName.substring(originName.lastIndexOf("."));//把文件后缀获取出来
            //这里判断一下后缀是否是jpg,png
            if(!".jpg".equals(suffix) && !".png".equals(suffix) && !".jpeg".equals(suffix))
                return new ResponseResult(5010,"文件格式不正确，请重新选择!");
            String newName = filename+suffix;//保存在服务器上的书籍图片名字就是uuid加上截取的后缀
            String fileUrl = datePath+"/"+newName;//书籍图片目录加本身的书籍图片文件
            //4、文件上传到阿里云服务器
            ossClient.putObject(bucketName, fileUrl, inputStream);
            String complete = "https://"+bucketName+"."+endpoint+"/"+fileUrl;//构建完整的书籍图片地址
            return new ResponseResult(200,"图片已上传至服务器",complete);
        } catch (OSSException | ClientException | IOException oe) {
            oe.printStackTrace();
            return new ResponseResult(5011,"图片上传服务器失败");
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    @Override
    public ResponseResult loadCarousel(MultipartFile multipartFile) {
        if(multipartFile.isEmpty()) return new ResponseResult(5012,"上传图片为空");
        // 创建OSSClient实例。，暂时不用环境变量的方式
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        //判断oss桶是否存在，不存在则创建一个
        if(!ossClient.doesBucketExist(bucketName)) {
            //创建一个bucker
            ossClient.createBucket(bucketName);
            //设置oss实例访问权限；公共读
            ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
        }
        try {
            //1、获取文件上传的流
            //虽然配置文件写了限制文件大小，但是我们需要自定义返回错误信息
            if(multipartFile.getSize()/1024/1024>9){
                return new ResponseResult(5013,"图片太大啦");
            }
            InputStream inputStream = multipartFile.getInputStream();
            //2、构建用户头像目录  head/userId/2024-03-03/图片
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String datePath = "carousel/" + dateFormat.format(new Date());//构建书籍图片存放的目录
            //3、获取文件名
            String originName = multipartFile.getOriginalFilename();//这是文件在本地的名字，包括后缀
            String filename = UUID.randomUUID().toString();//用uuid生成一个新的名字
            assert originName != null;
            String suffix = originName.substring(originName.lastIndexOf("."));//把文件后缀获取出来
            //这里判断一下后缀是否是jpg,png
            if(!".jpg".equals(suffix) && !".png".equals(suffix) && !".jpeg".equals(suffix))
                return new ResponseResult(5014,"文件格式不正确，请重新选择!");
            String newName = filename+suffix;//保存在服务器上的书籍图片名字就是uuid加上截取的后缀
            String fileUrl = datePath+"/"+newName;//书籍图片目录加本身的书籍图片文件
            //4、文件上传到阿里云服务器
            ossClient.putObject(bucketName, fileUrl, inputStream);
            String complete = "https://"+bucketName+"."+endpoint+"/"+fileUrl;//构建完整的书籍图片地址
            return new ResponseResult(200,"图片已上传至服务器",complete);
        } catch (OSSException | ClientException | IOException oe) {
            oe.printStackTrace();
            return new ResponseResult(5015,"图片上传服务器失败");
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}
